-
Notifications
You must be signed in to change notification settings - Fork 2.6k
trcaz - Industry onboarding #986
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 19.0
Are you sure you want to change the base?
Conversation
7ee5e1f
to
4b5f71c
Compare
[IMP] estate: add chapter 2 [IMP] estate: add chapter 3 [IMP] estate: add chapter 4 [IMP] estate: add chapter 5 [IMP] estate: add chapter 6 [IMP] estate: (chapter 7) add types, tags, & offers views/models and fix search group by & menu names [IMP] estate: add chapter 8 [IMP] estate: Chapter 10 [IMP] estate: add Chapter 11 [IMP] estate: apply some of Faruk's suggestions from the PR [IMP] estate: remove superfluous encoding line (runbot) [IMP] estate: add _ to UserError string parameters [IMP] estate: add chapter 12 [IMP] estate: fix the default date availability being computed only on upgrade [ADD] estate_account: add module manifest [IMP] estate: fix the default date lambda parameter error [IMP] estate_account: add chapter 13 [IMP] estate: add chapter 14 [IMP] estate, estate_account: fix author and license warning [IMP] estate: apply some PR suggestions [IMP] estate: prefix ondelete method with _unlink Co-authored-by: Cemal Faruk Güney <[email protected]> [IMP] estate: apply R&D string convention [IMP] estate: apply PR suggestions [IMP] estate_account: make action_property_sold more extensible and maintainable [IMP] estate, estate_account: implement tests and fix code to pass them [IMP] estate: implement test for garden uncheck behavior [IMP] estate: change test class names according to the conventions [IMP] estate: change references to self.properties[i] to their own variables for clarity [IMP] estate: change import style Co-authored-by: Cemal Faruk Güney <[email protected]> [IMP] estate: apply PR suggestions [IMP] estate: make test imports clean and not relative [IMP] estate_account: add test to check account.move creation on sell [IMP] estate_account: make test more robust by sorting invoice lines according to price [IMP] *: add empty tutorial commit
…e fields to property model and form view
…d in model and form
f77cd91
to
bdb9f65
Compare
Co-authored-by: Abdelrahman Rashed <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
great job, just some small things and you are good to go
<record id="api_public_write_rule" model="ir.rule"> | ||
<field name="name">Public users can't write</field> | ||
<field name="model_id" ref="real_estate_property_model"/> | ||
<field name="domain_force">[(0, '=', 1)]</field> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is the purpose of this rule?
the domain is false for all instances right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the tutorial said to allow read and write on the route (to allow the server action to be executed), but restrict the write user access with this domain
add an access right record to allow public users to read and write the model
prevent any write from the public user by adding a record rule for the write operation with an impossible domain (e.g. [('id', '=', False)])
<field name="x_bedrooms"/> | ||
<field name="x_living_area"/> | ||
<field name="x_expected_price"/> | ||
<field name="x_date_availability" optional="disabled"/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this set a disabled?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
excellent question
Co-authored-by: Abdelrahman Rashed <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well done. Just a few comments reading through the xml part. Don't hesitate to let me know if anything is unclear
{ | ||
'name': 'Estate (import)', | ||
'depends': [ | ||
'base', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Every module depends on base
, so base
is only mentioned if there is no other.
'base', |
<field name="name">x_garden_orientation</field> | ||
<field name="field_description">Garden Orientation</field> | ||
<field name="ttype">selection</field> | ||
<field name="selection">[('x_north', "North"), ('x_south', "South"), ('x_east', "East"), ('x_west', "West")]</field> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wasn't it asked to use ir.model.fields.selection
?
<field name="model_id" ref="real_estate_property_model" /> | ||
<field name="name">x_total_area</field> | ||
<field name="field_description">Total Area</field> | ||
<field name="ttype">float</field> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes not much sense, but since other areas are integers, this one should be an integer as well
|
||
<!-- Actions --> | ||
|
||
<record id="api_public_write_rule" model="ir.rule"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you have a security folder, this record should be there
<field name="model">x_estate.property</field> | ||
</record> | ||
|
||
<record model="ir.model.access" id="access_real_estate_property_public"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same, should be in security/
<field name="selection">True</field> | ||
<field name="selection">[('x_accepted', "Accepted"), ('x_refused', "Refused")]</field> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it makes no sense to define twice the same field (only last one is taken into account)
<field name="ttype">many2one</field> | ||
<field name="relation">res.partner</field> | ||
<field name="required">True</field> | ||
<field name="on_delete">cascade</field> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a bit 🤠 but fine
<field name="name">x_estate.property.offer.view.list</field> | ||
<field name="model">x_estate.property.offer</field> | ||
<field name="arch" type="xml"> | ||
<list string="Property offer list test string?"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👀
<field name="name">Property types</field> | ||
<field name="res_model">x_estate.property.type</field> | ||
<field name="view_mode">list</field> | ||
<field name="context">{'search_default_available': True}</field> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this work?
<field name="name">Property tags</field> | ||
<field name="res_model">x_estate.property.tag</field> | ||
<field name="view_mode">list</field> | ||
<field name="context">{'search_default_available': True}</field> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Went on and read your whole code. Overall super good, just noted a few things.
No need to update anything here, just food for thought
@@ -0,0 +1,5 @@ | |||
"id","name","sequence","property_ids","offer_ids","offer_count" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I bet you don't have to list all fields, only the one you define (and the required ones, obviously)
<record id="property_1" model="estate.property"> | ||
<field name="name">Big Villa</field> | ||
<field name="property_type_id" ref="property_type_1"/> | ||
<field name="state">new</field> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
default value, not necessary
<field name="state">new</field> |
def _unlink_check_status(self): | ||
for record in self: | ||
if record.state not in ['new', 'cancelled']: | ||
raise UserError(_("A property can only be deleted if its state is 'New' or 'Cancelled'")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We try to have less technical messages for end-users, something like
raise UserError(_("A property can only be deleted if its state is 'New' or 'Cancelled'")) | |
raise UserError(_("A property can only be deleted if it is a new one or if it was cancelled.")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also note that _()
has been mostly replaced by self.env._()
if not record.offer_ids: | ||
raise UserError(_("A property with no offers cannot be sold.")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't it too constraining the end user? You probably have specific cases where you want to bypass the "normal" flow and such conditions could be a burden for some users
from odoo import _, api, exceptions, fields, models | ||
from odoo.exceptions import UserError |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
from odoo import _, api, exceptions, fields, models | |
from odoo.exceptions import UserError | |
from odoo import _, api, fields, models | |
from odoo.exceptions import UserError |
<field name="bedrooms" /> | ||
<field name="living_area" filter_domain="[('living_area', '>=', self)]"/> | ||
<field name="facades" /> | ||
<filter name="available" string="Available" domain="['|', ('state', '=', 'new'), ('state', '=', 'offer_received')]"/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shorter (and maybe clearer) this way
<filter name="available" string="Available" domain="['|', ('state', '=', 'new'), ('state', '=', 'offer_received')]"/> | |
<filter name="available" string="Available" domain="[('state', 'in', ['new', 'offer_received'])]"/> |
} for record in self] | ||
|
||
def action_property_sold(self): | ||
invoice_vals = self.get_sold_property_invoice_values() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice way to do it
|
||
def action_property_sold(self): | ||
invoice_vals = self.get_sold_property_invoice_values() | ||
self.env['account.move'].create(invoice_vals) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I fear you need a sudo here, as not all you sellers will be able to create an invoice
self.invoice = self.env['account.move'].search(Domain('partner_id', '=', self.cozy_cottage.buyer_id.id) & Domain('move_type', '=', 'out_invoice')) | ||
self.assertTrue(self.invoice) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you only need to check the existence, use search_count with limit=1 (if you need the first record, then only limit=1)
self.invoice = self.env['account.move'].search(Domain('partner_id', '=', self.cozy_cottage.buyer_id.id) & Domain('move_type', '=', 'out_invoice')) | ||
self.assertTrue(self.invoice) | ||
|
||
sorted_invoice_lines = self.invoice.invoice_line_ids.sorted(key=lambda r: r.price_unit) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if the price of the house is really small? 🙃
No description provided.